<?php

namespace App\Console\Commands;

use App\Models\TaskModel;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;


class Kangxi extends Command
{
    private $cookie_jar;
    private $ch;
    private $time_range = [3, 10];   //等待时间范围,防被封
    private $kangxi_url = 'http://tool.httpcn.com/KangXi/So.asp';
    private $xinhuan_url = 'http://tool.httpcn.com/Zi/So.asp';  //?Tid=1&wd=%E7%8E%8B

    public function __construct()
    {
        parent::__construct();
        $this->cookie_jar = storage_path('pic.cookie');
        $this->ch = curl_init();
    }

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:kangxi';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $this->doit();
    }

    private function doit()
    {
        $tasks = TaskModel::where('status', '!=', '1')
            ->where(function ($query) {
                $query->whereNotNull('char')
                    ->where('char', '<>', '');
            })->get();
        $bar = $this->output->createProgressBar(count($tasks));

        foreach ($tasks as $task) {
            if ($this->KangxiTask($task->char)) {
                $task->status = 1;  //成功
                $task->save();
                $this->info("\t" . '康熙字 ' . $task->char . ' 入库成功!');
            } else if ($this->XinhuaTask($task->char)) {    //康熙字体没有的时候,用新华字典尝试
                $task->status = 1;  //成功
                $task->save();
                $this->info("\t" . '新华字典 ' . $task->char . ' 入库成功!');
            } else {
                $this->info("\t" . '--' . $task->char . ' 入库失败!');
            }
            $bar->advance();
            sleep(random_int(2, 5));
        }
        $bar->finish();
    }

    private function KangxiTask($char)
    {
        $flag = false;
        $response = $this->curl_post_302($this->kangxi_url, [
            'Tid' => 1,
            'wd' => $char, // URL 会自动编码为 %E9%99%88
        ]);
        $body = $response->getBody();
        if ($arr = $this->analyze($body, false)) {
            if (isset($arr['char']) && $arr['char'] != '') {
                try {
                    DB::table('kangxis')->insert($arr);
                } catch (QueryException $e) {
                    if ($e->getCode() != 23000) {
                        $this->warn("康熙字保存失败: {$char}, {$e->getMessage()}");
                    }
                }
                $flag = true;
            }
        }
        return $flag;
    }

    private function XinhuaTask($char)
    {
        $flag = false;
        $response = $this->curl_post_302($this->xinhuan_url, [
            'Tid' => 1,
            'wd' => $char, // URL 会自动编码为 %E9%99%88
        ]);
        $body = $response->getBody();
        if ($arr = $this->analyze($body, true)) {
            if (isset($arr['char']) && $arr['char'] != '') {
                DB::table('kangxis')->insert($arr);
                $flag = true;
            }
        }
        return $flag;
    }

    private function unicodeSafeSpace($str)
    {
        return preg_replace([
            '/\p{Zs}/u',      // 所有分隔空格的Unicode类别
            '/\t/',            // 制表符
            '/\r\n|\n|\r/'     // 各种换行
        ], '', $str);
    }

    private function analyze($data, $zidian)
    {
        $res = [];
        //搜索字
        preg_match('#『(.*?)』#', $data, $matches);
        if (isset($matches[1])) $res['char'] = $matches[1];

        //异体字
        preg_match('#<span class="b">异体字：</span>(<a[^>]*>([^<]+)</a>)+#', $data, $matches);
        if (isset($matches[0])) {
            preg_match_all('#<a[^>]*>([^<]+)</a>#', $matches[0], $matches);
            if (isset($matches[1])) $res['yiti'] = implode(',', $matches[1]);
        }

        //繁体字
        preg_match('#<span class="b">繁体字：</span><a[^>]*?>([^<]*?)</a>#', $data, $matches);
        if (isset($matches[1])) $res['fanti'] = $matches[1];

        //简体字
        preg_match('#<span class="b">简体字：</span><a[^>]*?>([^<]*?)</a>#', $data, $matches);
        if (isset($matches[1])) $res['jianti'] = $matches[1];

        //拼音
        preg_match('#<span class="b">拼音：</span><span class="pinyin">(.*?)</span>#', $data, $matches);
        if (isset($matches[1])) {
            preg_match_all('#[^>]+(?=<script>)#', $matches[1], $matches);
            if (isset($matches[0])) $res['pinying'] = implode(',', $matches[0]);
        }
        //注音
        preg_match('#<span class="b">注音：</span><span class="pinyin">(.*?)</span>#', $data, $matches);
        if (isset($matches[1])) {
            preg_match_all('#[^>]+(?=<script>)#', $matches[1], $matches);
            if (isset($matches[0])) $res['zhuying'] = implode(',', $matches[0]);
        }

        //搜索字
        preg_match('#『(.*?)』#', $data, $matches);
        if (isset($matches[1])) $res['jianti'] = $matches[1];

        //简体部首,部首笔画,总笔画
        preg_match('#<span class="b">简体部首：</span>([^<]*?)<span class="b">部首笔画：</span>([^<]*?)<span class="b">总笔画：</span>([^<]*?)<br>#', $data, $matches);
        if (isset($matches[1])) $res['jianti_bushou'] = $this->unicodeSafeSpace($matches[1]);
        if (isset($matches[2])) $res['jianti_bushou_bihua'] = $this->unicodeSafeSpace($matches[2]);
        if (isset($matches[3])) $res['jianti_bihua'] = $this->unicodeSafeSpace($matches[3]);

        //繁体部首,部首笔画,总笔画
        preg_match('#<span class="b">繁体部首：</span>([^<]*?)<span class="b">部首笔画：</span>([^<]*?)<span class="b">总笔画：</span>([^<]*?)<br />#', $data, $matches);
        if (count($matches) < 3) {
            preg_match('#<span class="b">繁体部首：</span>([^<]*?)<span class="b">部首笔画：</span>([^<]*?)<span class="b">总笔画：</span>([^<]*?)</p>#', $data, $matches);
        }
        if (isset($matches[1])) $res['fanti_bushou'] = $this->unicodeSafeSpace($matches[1]);
        if (isset($matches[2])) $res['fanti_bushou_bihua'] = $this->unicodeSafeSpace($matches[2]);
        if (isset($matches[3])) $res['fanti_bihua'] = $this->unicodeSafeSpace($matches[3]);

        //没写繁体简体
        preg_match('#<span class="b">部首：</span>([^<]*?)<span class="b">部首笔画：</span>([^<]*?)<span class="b">总笔画：</span>([^<]*?)<br />#', $data, $matches);
        if (count($matches) < 3) {
            preg_match('#<span class="b">部首：</span>([^<]*?)<span class="b">部首笔画：</span>([^<]*?)<span class="b">总笔画：</span>([^<]*?)</p>#', $data, $matches);
        }
        if (isset($matches[1])) $res['bushou'] = $this->unicodeSafeSpace($matches[1]);
        if (isset($matches[2])) $res['bushou_bihua'] = $this->unicodeSafeSpace($matches[2]);
        if (isset($matches[3])) $res['bihua'] = $this->unicodeSafeSpace($matches[3]);

        if ((!isset($res['jianti']) && isset($res['fanti'])) || !isset($res['fanti']) && isset($res['char'])) {
            $res['jianti'] = $res['char'];
        }

        //康熙笔画
        preg_match('#<span class="b">康熙字典笔画</span>\((.*)\)#u', $data, $matches);
        if (isset($matches[1])) {
            preg_match_all('#([\x{4e00}-\x{9fa5}]+):(\d*)；#u', $this->unicodeSafeSpace($matches[1]), $matches);

            if (isset($matches[1])) $res['kangxizi'] = implode(',', $matches[1]);
            if (isset($matches[1])) $res['kangxi_bihua'] = implode(',', $matches[2]);
        }

        //输入法编码-五笔
        preg_match('#<span class="b">五笔86：</span>([^<]*?)<span class="b">五笔98：</span>([^<]*?)<span class="b">仓颉：</span>([^<]*?)<br />#', $data, $matches);
        if (isset($matches[1])) $res['wubi86'] = $this->unicodeSafeSpace($matches[1]);
        if (isset($matches[1])) $res['wubi98'] = $this->unicodeSafeSpace($matches[2]);
        if (isset($matches[1])) $res['cangjie'] = $this->unicodeSafeSpace($matches[3]);

        //计算机编码
        preg_match('#<span class="b">四角号码：</span>([^<]*?)<span class="b">UniCode：</span>([^<]*?)<span class="b">规范汉字编号：</span>([^<]*?)<br />#', $data, $matches);
        if (isset($matches[1])) $res['sijiao'] = $this->unicodeSafeSpace($matches[1]);
        if (isset($matches[1])) $res['unicode'] = $this->unicodeSafeSpace($matches[2]);
        if (isset($matches[1])) $res['hanbian'] = $this->unicodeSafeSpace($matches[3]);

        //汉字五行
        preg_match('#汉字五行：([\x{4e00}-\x{9fa5}]+)#u', $data, $matches);
        if (isset($matches[1])) $res['wuxing'] = $matches[1];

        //吉凶寓意
        preg_match('#吉凶寓意：([\x{4e00}-\x{9fa5}]+)#u', $data, $matches);
        if (isset($matches[1])) $res['jixiong'] = $matches[1];

        //是否为常用字
        preg_match('#是否为常用字：([\x{4e00}-\x{9fa5}]+)#u', $data, $matches);
        if (isset($matches[1])) $res['changyong'] = $matches[1];

        //姓名学
        preg_match('#姓名学：([^<]+)#', $data, $matches);
        if (isset($matches[1])) $res['xingmingxue'] = $matches[1];

        return $res;
    }

//    private $pre_url = "https://tool.httpcn.com/Html/Zi/39/KOXVILMEPWRNTBILXV.shtml";
    private function curl_post_302($url, $arrs)
    {
        $response = Http::withHeaders([
            'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Accept-Encoding' => 'gzip, deflate, br, zstd',
            'Accept-Charset' => 'utf-8',
            'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8',
            'Priority' => 'u=0, i',
//            'Referer' => $this->pre_url,
            'Sec-Ch-Ua' => '"Chromium";v="134", "Not:A-Brand";v="24", "Google Chrome";v="134"',
            'Sec-Ch-Ua-Mobile' => '?0',
            'Sec-Ch-Ua-Platform' => '"macOS"',
            'Sec-Fetch-Dest' => 'document',
            'Sec-Fetch-Mode' => 'navigate',
            'Sec-Fetch-Site' => 'same-origin',
            'Sec-Fetch-User' => '?1',
            'Upgrade-Insecure-Requests' => '1',
            'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36',
        ])->get($url, $arrs);
//        $this->pre_url = $response->effectiveUri();
        return $response;
    }

}
